package com.qf.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.qf.config.RedisKeyConfig;
import com.qf.dao.UserDao;
import com.qf.entity.User;
import com.qf.param.*;
import com.qf.service.UserService;
import com.qf.upload.FileUpload;
import com.qf.util.AliSmsUtil;
import com.qf.util.TokenUtil;
import com.qf.vo.R;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Base64Utils;
import org.springframework.web.multipart.MultipartFile;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 用户表(User)表服务实现类
 *
 */
@Service("userService")
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {
    private final UserDao userDao;
    private final StringRedisTemplate template;
    /**
     *用户注册
     * @param user
     * @return   R
     */
    @Transactional
    @Override
    public R register(UserRegister user) {
        //手机号作为用户唯一性校验
//        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
//        User registerUser = userDao.selectOne(wrapper.eq(User::getPhone, user.getPhone()));
//        if(registerUser!=null){
//            return R.fail("该手机号已被注册，请检查手机号码是否正确！");
//        }
        //密码加密后在存入数据库
        User user1 = userDao.selectByPhone(user.getPhone());
        if (user1 != null){
           return R.fail("手机号已被注册");
        }
        String password = SecureUtil.sha1(SecureUtil.md5(user.getPassword()));
        User userEntity = new User();
        BeanUtils.copyProperties(user, userEntity);
        userEntity.setPassword(password);
        if(userDao.insert(userEntity)>0){
            return R.ok("注册成功");
        }
        return R.fail("注册失败");
    }

    @Override
    public R sendCode(String phone) {
        return null;


//        //检查手机号是否已被注册
//        User user = userDao.selectOne(new LambdaQueryWrapper<User>().eq(User::getPhone,phone));
//        if(user==null){
//            return R.fail("请检查手机号是否正确");
//        }
//        //生成随机6位数验证码
//        String code = RandomUtil.randomNumbers(6);
//        //发送验证码
//        System.out.println(code);
//        if(AliSmsUtil.sendCode(AliSmsUtil.SMS_TEM_CODE,phone,code)){
//            //发送成功将验证码存储在redis中
//            template.opsForValue().set(RedisKeyConfig.SMS_LCODE+phone,code,RedisKeyConfig.SMS_CODE_TIME,TimeUnit.SECONDS);
//            return R.ok(null);
//        }
//        return R.fail("验证码发送失败");
    }

    @Override
    public R loginCode(UserLoginCode code) {
        //检查redis中是否有验证码
        if(template.hasKey(RedisKeyConfig.SMS_LCODE+code.getPhone())){
            //将前端输入的验证码与redis中的验证码进行比对
            if(Objects.equals(code.getCode(),template.opsForValue().get(RedisKeyConfig.SMS_LCODE+code.getPhone()))){
                User user = userDao.selectOne(new LambdaQueryWrapper<User>().eq(User::getPhone,code.getPhone()));
                //生成令牌
                String token = TokenUtil.createToken(user.getId()+"");
                //存储在redis中 有效期6个小时
                template.opsForValue().set(RedisKeyConfig.USER_TOKEN+token,user.getId()+"",6, TimeUnit.HOURS);
                //删除验证码
                template.delete(RedisKeyConfig.SMS_LCODE+code.getPhone());
                //返回信息
                Map<String, Object> result = new HashMap<>();
                result.put("token",token);
                user.setPassword("");
                result.put("user",user);
                return R.ok(result);
            }
        }
        return R.fail("验证码有误请重新输入");
    }

    @Override
    public R updatePass(String password, String token) {
        //从redis中获取用户id
        String uid = template.opsForValue().get(RedisKeyConfig.USER_TOKEN+token);
        //密码加密
        String pass = SecureUtil.sha1(SecureUtil.md5(password));
        User user = new User();
        user.setId(Integer.parseInt(uid));
        user.setPassword(pass);
        user.setUpdateTime(new Date());
        if(userDao.updateById(user)>0){
            //修改成功 重新登录 删除旧令牌
            template.delete(RedisKeyConfig.USER_TOKEN+token);
            return R.ok(null);
        }
        return R.fail("密码修改失败，请重试");
    }

    @Override
    public R sendCodeFindPass(String phone) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getPhone,phone);
        User user = userDao.selectOne(wrapper);
        if(user!=null){
            //创建验证码
            String code = RandomUtil.randomNumbers(6);
            //发送验证码
            System.out.println(code);
            if(AliSmsUtil.sendCode(AliSmsUtil.SMS_TEM_CODE,phone,code)){
                //发送成功将验证码存储在redis中
                template.opsForValue().set(RedisKeyConfig.SMS_FCODE+phone,code,RedisKeyConfig.SMS_CODE_TIME,TimeUnit.SECONDS);
                return R.ok(null);
            }
            return R.fail("验证码发送失败");
        }
        return R.fail("手机号未注册，请检查手机号是否正确");
    }

    @Override
    public R findPass(UserFind userFind) {
        //校验验证码
        String key = RedisKeyConfig.SMS_FCODE+userFind.getPhone();
        if(template.hasKey(key)){
            if(template.opsForValue().get(key).equals(userFind.getCode())){
                User user = userDao.selectOne(new LambdaQueryWrapper<User>().eq(User::getPhone, userFind.getPhone()));
                //找到用户 修改用户密码并加密
                String pass = SecureUtil.sha1(SecureUtil.md5(user.getPassword()));
                user.setPassword(pass);
                user.setUpdateTime(new Date());
                if(userDao.updateById(user)>0){
                    //修改后删除redis中的验证码
                    template.delete(key);
                    return R.ok(null);
                }
            }
        }
        return R.fail("请检查验证码是否已发送");
    }

    /**
     * 用户登录
     * @param userLogin
     * @return
     */
    @Override
    public R login(UserLogin userLogin) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getPhone,userLogin.getPhone());
        wrapper.eq(User::getPassword, SecureUtil.sha1(SecureUtil.md5(userLogin.getPassword())));
        User user = userDao.selectOne(wrapper);
        if(user!=null){
            //生成令牌
            String token = TokenUtil.createToken(user.getId() + "");

            //存储在redis中 有效期6个小时
            template.opsForValue().set(RedisKeyConfig.USER_TOKEN+token,user.getId()+"",6, TimeUnit.HOURS);
            //返回信息
            Map<String, Object> result = new HashMap<>();
            result.put("token",token);
            result.put("user",user);
            return R.ok(result);
        }
        return R.fail("手机号或密码错误");
    }

    @Transactional
    @Override
    public R updateInfo(UserUpate userUpate, String token) {
//        String uid = template.opsForValue().get(RedisKeyConfig.USER_TOKEN + token);
//        if(uid==null){
//            return R.fail("未登录账号，请先登录以执行后续操作");
//        }
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getId,3);
        User user = userDao.selectOne(wrapper);
        user.setUpdateTime(new Date());
        BeanUtils.copyProperties(userUpate, user);
        if(userDao.updateById(user)>0){
            return R.ok("修改成功");
        }
        return R.fail("修改失败，请重试");
    }

}

